import logging
import os
from typing import List, Dict, Any, Optional
from datetime import datetime
from sqlalchemy.orm import Session
from sqlalchemy import desc
from app.config.settings import settings
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage, AIMessage, SystemMessage
from app.services.search_service import search_and_answer
from app.services.auth_service import auth_service
from app.models.session import Session, Message

logger = logging.getLogger(__name__)

class ChatManager:
    """聊天管理器（与用户相关）"""
    def __init__(self):
        logger.info("ChatManager initialized successfully")

    def create_chat_model(self, use_reasoner: bool = False):
        """创建DeepSeek聊天模型实例"""
        if use_reasoner:
            model = settings.deepseek_reasoner_model
            config = settings.deepseek_reasoner_config
            logger.info(f"Creating reasoner model with parameters: model={model}, "
                        f"temperature={config['temperature']}, "
                        f"max_tokens={config['max_tokens']}, "
                        f"api_base={settings.deepseek_base_url}")
        else:
            model = settings.deepseek_model
            config = settings.deepseek_chat_config
            logger.info(f"Creating chat model with parameters: model={model}, "
                        f"temperature={config['temperature']}, "
                        f"max_tokens={config['max_tokens']}, "
                        f"api_base={settings.deepseek_base_url}")
        
        return ChatOpenAI(
            model=model,
            temperature=config["temperature"],
            max_tokens=config["max_tokens"],
            request_timeout=config["request_timeout"],
            openai_api_key=settings.deepseek_api_key,
            openai_api_base=settings.deepseek_base_url
        )

    def format_user_profile_data(self, profile_data: Dict[str, Any]) -> Dict[str, str]:
        """格式化用户画像数据为提示词模板所需格式"""
        try:
            # 用户基本信息
            user_basic_info = f"年龄组: {profile_data.get('age_group', '未知')}\n"
            user_basic_info += f"性别: {profile_data.get('gender', '未知')}\n"
            user_basic_info += f"地区: {profile_data.get('location', '未知')}"

            # 用户偏好设置
            favorite_genres = profile_data.get('favorite_genres', [])
            favorite_directors = profile_data.get('favorite_directors', [])
            favorite_actors = profile_data.get('favorite_actors', [])
            
            user_preferences = f"喜欢的电影类型: {', '.join(favorite_genres) if favorite_genres else '未设置'}\n"
            user_preferences += f"喜欢的导演: {', '.join(favorite_directors) if favorite_directors else '未设置'}\n"
            user_preferences += f"喜欢的演员: {', '.join(favorite_actors) if favorite_actors else '未设置'}"

            # 用户情感偏好
            emotional_prefs = profile_data.get('emotional_preferences', [])
            mood_history = profile_data.get('mood_history', [])
            
            if emotional_prefs:
                user_emotional_preferences = f"情感偏好: {', '.join(emotional_prefs)}\n"
            else:
                user_emotional_preferences = "情感偏好: 未设置\n"
            
            if mood_history:
                recent_moods = mood_history[-3:] if len(mood_history) > 3 else mood_history
                user_emotional_preferences += f"最近心情记录: {', '.join(recent_moods)}"
            else:
                user_emotional_preferences += "最近心情记录: 暂无记录"

            # 观影历史（暂时使用空数据，因为当前数据结构中没有详细的观影历史）
            viewing_history = "暂无详细观影历史记录"

            return {
                'user_basic_info': user_basic_info,
                'user_preferences': user_preferences,
                'user_emotional_preferences': user_emotional_preferences,
                'viewing_history': viewing_history
            }
        except Exception as e:
            logger.error(f"格式化用户画像数据失败: {e}")
            return {
                'user_basic_info': '用户信息获取失败',
                'user_preferences': '偏好信息获取失败',
                'user_emotional_preferences': '情感信息获取失败',
                'viewing_history': '观影历史获取失败'
            }
    
    def _filter_thinking_content(self, content: str) -> str:
        """过滤deepseek-reasoner的思考内容，只保留最终答案"""
        try:
            # deepseek-reasoner的输出格式通常包含<think>...</think>标签
            # 我们需要过滤掉这些思考过程，只保留最终答案
            import re
            
            # 移除<think>...</think>标签及其内容
            filtered_content = re.sub(r'<think>.*?</think>', '', content, flags=re.DOTALL)
            
            # 移除可能的其他思考标记
            filtered_content = re.sub(r'思考过程：.*?(?=\n\n|$)', '', filtered_content, flags=re.DOTALL)
            filtered_content = re.sub(r'分析：.*?(?=\n\n|$)', '', filtered_content, flags=re.DOTALL)
            
            # 清理多余的空行
            filtered_content = re.sub(r'\n\s*\n', '\n\n', filtered_content)
            filtered_content = filtered_content.strip()
            
            # 如果过滤后内容为空，返回原内容
            if not filtered_content:
                return content
                
            return filtered_content
        except Exception as e:
            logger.warning(f"过滤思考内容失败: {e}，返回原内容")
            return content
    
    def classify_user_intent(self, message: str) -> str:
        """使用大模型分析用户意图"""
        try:
            logger.info(f"开始分析用户意图: {message[:50]}...")
            
            # 创建专门用于意图分类的模型实例
            llm = ChatOpenAI(
                model=settings.deepseek_model,
                temperature=settings.intent_classification_config["temperature"],
                max_tokens=settings.intent_classification_config["max_tokens"],
                request_timeout=settings.intent_classification_config["request_timeout"],
                openai_api_key=settings.deepseek_api_key,
                openai_api_base=settings.deepseek_base_url
            )
            
            # 构建意图分类消息
            messages = [
                SystemMessage(content=settings.deepseek_system_prompts["intent_classification"]),
                HumanMessage(content=message)
            ]
            
            # 调用模型进行意图分类
            response = llm.invoke(messages)
            intent = response.content.strip().lower()
            
            # 验证返回的意图类型是否有效
            valid_intents = ["movie_recommendation", "movie_analysis", "plot_explanation", "movie_qa", "general_chat"]
            if intent not in valid_intents:
                logger.warning(f"无效的意图分类结果: {intent}，使用默认值")
                intent = "general_chat"
            
            logger.info(f"意图分析结果: {intent}")
            return intent
            
        except Exception as e:
            logger.error(f"意图分析失败: {e}，使用默认意图")
            return "general_chat"

    def process_chat_message(self, user_id: str, message: str, session_id: Optional[int] = None, enable_search: bool = False, enable_personalization: bool = False, enable_deep_thinking: bool = False, search_engine: str = "tavily", db: Session = None):
        """按用户处理消息并返回助手响应"""
        logger.info(f"Processing message for user {user_id}. Session: {session_id}, Enable search: {enable_search}, Enable personalization: {enable_personalization}, Enable deep thinking: {enable_deep_thinking}, Search engine: {search_engine}")
        
        # 获取或创建会话
        if session_id:
            session = db.query(Session).filter(Session.id == session_id, Session.user_id == int(user_id)).first()
            if not session:
                raise ValueError(f"会话 {session_id} 不存在或不属于用户 {user_id}")
        else:
            # 创建新会话
            session_count = db.query(Session).filter(Session.user_id == int(user_id)).count()
            session = Session(
                user_id=int(user_id),
                session_title=f"会话 {session_count + 1}",
                session_type="general",
                status="active"
            )
            db.add(session)
            db.commit()
            db.refresh(session)
        
        # 获取历史消息
        history_messages = db.query(Message).filter(
            Message.session_id == session.id
        ).order_by(Message.created_at).limit(settings.deepseek_chat_config["max_history_messages"] * 2).all()
        
        # 检查是否为第一条消息（用于自动生成会话标题）
        is_first_message = len(history_messages) == 0
        
        # 转换历史消息格式
        history = []
        for msg in history_messages:
            history.append({
                "role": msg.role,
                "content": msg.content,
                "timestamp": msg.created_at.strftime("%Y-%m-%d %H:%M:%S") if msg.created_at else None
            })
        
        # 第一步：进行意图分析
        user_intent = self.classify_user_intent(message)
        logger.info(f"用户意图识别结果: {user_intent}")
        
        should_search = enable_search
        llm = self.create_chat_model(use_reasoner=enable_deep_thinking)

        # 搜索逻辑（如果启用）
        if should_search:
            logger.info(f"Search enabled, invoking search service for user {user_id}")
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")  # 提前定义timestamp
            try:
                # 调用搜索服务获取结果
                search_result = search_and_answer(query=message, user_question=message, llm=llm)
                
                # 保存用户消息到数据库
                user_message = Message(
                    session_id=session.id,
                    user_id=int(user_id),
                    role="user",
                    content=message,
                    message_type="text"
                )
                db.add(user_message)
                
                # 保存AI回复到数据库
                ai_message = Message(
                    session_id=session.id,
                    user_id=int(user_id),
                    role="assistant",
                    content=search_result or "搜索失败",
                    message_type="text"
                )
                db.add(ai_message)
                
                # 更新会话的更新时间
                session.updated_at = datetime.now()
                
                # 如果是第一条消息，自动生成会话标题
                if is_first_message:
                    try:
                        new_title = self.generate_session_title(message)
                        session.session_title = new_title
                        logger.info(f"自动生成会话标题: {new_title}")
                    except Exception as e:
                        logger.error(f"自动生成会话标题失败: {e}")
                
                db.commit()
                
                return {
                    "response": search_result or "未找到相关信息",
                    "timestamp": timestamp,
                    "search_used": True,
                    "personalization_used": False,
                    "deep_thinking_used": enable_deep_thinking,
                    "search_engine": search_engine,
                    "user_intent": user_intent,
                    "session_id": session.id,
                    "specialized_mode": user_intent if user_intent != "general_chat" else None
                }
            except Exception as e:
                logger.error(f"Search service failed for user {user_id}: {e}")
                
                # 保存用户消息到数据库
                user_message = Message(
                    session_id=session.id,
                    user_id=int(user_id),
                    role="user",
                    content=message,
                    message_type="text"
                )
                db.add(user_message)
                
                # 保存错误回复到数据库
                ai_message = Message(
                    session_id=session.id,
                    user_id=int(user_id),
                    role="assistant",
                    content="搜索服务异常",
                    message_type="text"
                )
                db.add(ai_message)
                
                # 更新会话的更新时间
                session.updated_at = datetime.now()
                
                # 如果是第一条消息，自动生成会话标题
                if is_first_message:
                    try:
                        new_title = self.generate_session_title(message)
                        session.session_title = new_title
                        logger.info(f"自动生成会话标题: {new_title}")
                    except Exception as e:
                        logger.error(f"自动生成会话标题失败: {e}")
                
                db.commit()
                
                return {
                    "response": "搜索服务异常",
                    "timestamp": timestamp,
                    "search_used": True,
                    "personalization_used": False,
                    "deep_thinking_used": enable_deep_thinking,
                    "search_engine": search_engine,
                    "user_intent": user_intent,
                    "session_id": session.id,
                    "specialized_mode": user_intent if user_intent != "general_chat" else None
                }
        
        # 个性化推荐逻辑（如果启用）
        if enable_personalization and db:
            logger.info(f"Personalization enabled, getting user profile for user {user_id}")
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            try:
                # 获取用户画像数据
                profile_result = auth_service.get_user_profile_data(db, int(user_id))
                if profile_result.get('success') and profile_result.get('data'):
                    profile_data = profile_result['data']
                    # 格式化用户画像数据
                    formatted_profile = self.format_user_profile_data(profile_data)
                    
                    # 使用个性化提示词模板
                    personalized_prompt = settings.deepseek_system_prompts["personalized"].format(**formatted_profile)
                    
                    # 构建消息列表
                    messages = [SystemMessage(content=personalized_prompt)]
                    
                    # 添加历史消息
                    for msg in history[-settings.deepseek_chat_config["max_history_messages"]:]:
                        if msg["role"] == "user":
                            messages.append(HumanMessage(content=msg["content"]))
                        elif msg["role"] == "assistant":
                            messages.append(AIMessage(content=msg["content"]))
                    
                    # 添加当前用户消息
                    messages.append(HumanMessage(content=message))
                    
                    # 调用LLM模型获取个性化响应
                    llm = self.create_chat_model(use_reasoner=enable_deep_thinking)
                    response = llm.invoke(messages)
                    response_content = response.content
                    
                    # 保存用户消息到数据库
                    user_message = Message(
                        session_id=session.id,
                        user_id=int(user_id),
                        role="user",
                        content=message,
                        message_type="text"
                    )
                    db.add(user_message)
                    
                    # 保存AI回复到数据库
                    ai_message = Message(
                        session_id=session.id,
                        user_id=int(user_id),
                        role="assistant",
                        content=response_content,
                        message_type="text"
                    )
                    db.add(ai_message)
                    
                    # 更新会话的更新时间
                    session.updated_at = datetime.now()
                    
                    # 如果是第一条消息，自动生成会话标题
                    if is_first_message:
                        try:
                            new_title = self.generate_session_title(message)
                            session.session_title = new_title
                            logger.info(f"自动生成会话标题: {new_title}")
                        except Exception as e:
                            logger.error(f"自动生成会话标题失败: {e}")
                    
                    db.commit()
                    
                    logger.info(f"Personalized response generated for user {user_id}")
                    return {
                        "response": response_content,
                        "timestamp": timestamp,
                        "search_used": False,
                        "personalization_used": True,
                        "deep_thinking_used": enable_deep_thinking,
                        "search_engine": None,
                        "user_intent": user_intent,
                        "session_id": session.id,
                        "specialized_mode": user_intent if user_intent != "general_chat" else None
                    }
                else:
                    logger.warning(f"No profile data found for user {user_id}, falling back to default mode")
            except Exception as e:
                logger.error(f"Personalization service failed for user {user_id}: {e}")
                
                # 保存用户消息到数据库
                user_message = Message(
                    session_id=session.id,
                    user_id=int(user_id),
                    role="user",
                    content=message,
                    message_type="text"
                )
                db.add(user_message)
                
                # 保存错误回复到数据库
                ai_message = Message(
                    session_id=session.id,
                    user_id=int(user_id),
                    role="assistant",
                    content="个性化服务异常，已切换到普通模式",
                    message_type="text"
                )
                db.add(ai_message)
                
                # 更新会话的更新时间
                session.updated_at = datetime.now()
                
                # 如果是第一条消息，自动生成会话标题
                if is_first_message:
                    try:
                        new_title = self.generate_session_title(message)
                        session.session_title = new_title
                        logger.info(f"自动生成会话标题: {new_title}")
                    except Exception as e:
                        logger.error(f"自动生成会话标题失败: {e}")
                
                db.commit()
                
                return {
                    "response": "个性化服务异常，已切换到普通模式",
                    "timestamp": timestamp,
                    "search_used": False,
                    "personalization_used": False,
                    "deep_thinking_used": False,
                    "search_engine": None,
                    "user_intent": user_intent,
                    "session_id": session.id,
                    "specialized_mode": user_intent if user_intent != "general_chat" else None
                }
        
        # 普通LLM对话逻辑
        # 1. 根据意图选择系统提示词
        if user_intent in ["movie_recommendation", "movie_analysis", "plot_explanation", "movie_qa"]:
            system_prompt = settings.deepseek_system_prompts[user_intent]
            logger.info(f"使用专业提示词: {user_intent}")
        else:
            system_prompt = settings.deepseek_system_prompts["default"]
            logger.info("使用默认提示词")
        
        # 2. 构建消息列表
        messages = [SystemMessage(content=system_prompt)]
        # 3. 添加历史消息
        for msg in history[-settings.deepseek_chat_config["max_history_messages"]:]:
            if msg["role"] == "user":
                messages.append(HumanMessage(content=msg["content"]))
            elif msg["role"] == "assistant":
                messages.append(AIMessage(content=msg["content"]))
        # 4. 添加当前用户消息
        messages.append(HumanMessage(content=message))
        try:
            # 4. 调用LLM模型获取响应
            if enable_deep_thinking:
                logger.info(f"Invoking DeepSeek Reasoner model for user {user_id}")
                llm = self.create_chat_model(use_reasoner=True)
            else:
                logger.info(f"Invoking LLM model for user {user_id}")
                llm = self.create_chat_model(use_reasoner=False)
            
            response = llm.invoke(messages)
            response_content = response.content
            
            # 如果启用深度思考，过滤掉思考过程，只保留最终答案
            if enable_deep_thinking and response_content:
                response_content = self._filter_thinking_content(response_content)
            
            logger.info(f"Successfully received response from {'Reasoner' if enable_deep_thinking else 'LLM'} for user {user_id}")
        except Exception as e:
            logger.error(f"LLM调用失败: {e}")
            response_content = settings.deepseek_system_prompts["error_fallback"]
        # 5. 保存对话历史到数据库
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
        # 保存用户消息
        user_message = Message(
            session_id=session.id,
            user_id=int(user_id),
            role="user",
            content=message,
            message_type="text"
        )
        db.add(user_message)
        
        # 保存AI回复
        ai_message = Message(
            session_id=session.id,
            user_id=int(user_id),
            role="assistant",
            content=response_content,
            message_type="text"
        )
        db.add(ai_message)
        
        # 更新会话的更新时间
        session.updated_at = datetime.now()
        
        # 如果是第一条消息，自动生成会话标题
        if is_first_message:
            try:
                new_title = self.generate_session_title(message)
                session.session_title = new_title
                logger.info(f"自动生成会话标题: {new_title}")
            except Exception as e:
                logger.error(f"自动生成会话标题失败: {e}")
        
        db.commit()
        
        return {
            "response": response_content,
            "timestamp": timestamp,
            "search_used": False,
            "personalization_used": False,
            "deep_thinking_used": enable_deep_thinking,
            "search_engine": None,
            "user_intent": user_intent,
            "session_id": session.id,
            "specialized_mode": user_intent if user_intent != "general_chat" else None
        }

    def get_chat_history(self, user_id: str, session_id: Optional[int] = None, db: Session = None) -> List[Dict[str, Any]]:
        """获取用户对话历史"""
        if not db:
            return []
        
        query = db.query(Message).filter(Message.user_id == int(user_id))
        
        if session_id:
            query = query.filter(Message.session_id == session_id)
        
        messages = query.order_by(Message.created_at).all()
        
        history = []
        for msg in messages:
            history.append({
                "role": msg.role,
                "content": msg.content,
                "timestamp": msg.created_at.strftime("%Y-%m-%d %H:%M:%S") if msg.created_at else None,
                "session_id": msg.session_id
            })
        
        return history

    def clear_chat_history(self, user_id: str, session_id: Optional[int] = None, db: Session = None):
        """清空用户对话历史"""
        if not db:
            return
        
        query = db.query(Message).filter(Message.user_id == int(user_id))
        
        if session_id:
            query = query.filter(Message.session_id == session_id)
        
        query.delete()
        db.commit()
    
    def get_user_sessions(self, user_id: str, db: Session = None) -> List[Dict[str, Any]]:
        """获取用户的所有会话"""
        if not db:
            return []
        
        sessions = db.query(Session).filter(
            Session.user_id == int(user_id),
            Session.status == "active"
        ).order_by(desc(Session.updated_at)).all()
        
        return [session.to_dict() for session in sessions]
    
    def create_session(self, user_id: str, session_title: str = None, db: Session = None) -> Dict[str, Any]:
        """创建新会话"""
        if not db:
            return {"success": False, "message": "数据库连接失败"}
        
        try:
            # 如果没有提供标题，自动生成
            if not session_title:
                session_count = db.query(Session).filter(Session.user_id == int(user_id)).count()
                session_title = f"会话 {session_count + 1}"
            
            session = Session(
                user_id=int(user_id),
                session_title=session_title,
                session_type="general",
                status="active"
            )
            
            db.add(session)
            db.commit()
            db.refresh(session)
            
            return {
                "success": True,
                "session": session.to_dict(),
                "message": "会话创建成功"
            }
        except Exception as e:
            logger.error(f"创建会话失败: {e}")
            db.rollback()
            return {"success": False, "message": f"创建会话失败: {str(e)}"}
    
    def delete_session(self, user_id: str, session_id: int, db: Session = None) -> Dict[str, Any]:
        """删除会话"""
        if not db:
            return {"success": False, "message": "数据库连接失败"}
        
        try:
            session = db.query(Session).filter(
                Session.id == session_id,
                Session.user_id == int(user_id)
            ).first()
            
            if not session:
                return {"success": False, "message": "会话不存在或无权限"}
            
            # 删除会话（级联删除消息）
            db.delete(session)
            db.commit()
            
            return {"success": True, "message": "会话删除成功"}
        except Exception as e:
            logger.error(f"删除会话失败: {e}")
            db.rollback()
            return {"success": False, "message": f"删除会话失败: {str(e)}"}
    
    def rename_session(self, user_id: str, session_id: int, new_title: str, db: Session = None) -> Dict[str, Any]:
        """重命名会话"""
        if not db:
            return {"success": False, "message": "数据库连接失败"}
        
        try:
            session = db.query(Session).filter(
                Session.id == session_id,
                Session.user_id == int(user_id)
            ).first()
            
            if not session:
                return {"success": False, "message": "会话不存在或无权限"}
            
            session.session_title = new_title
            session.updated_at = datetime.now()
            db.commit()
            
            return {
                "success": True,
                "session": session.to_dict(),
                "message": "会话重命名成功"
            }
        except Exception as e:
            logger.error(f"重命名会话失败: {e}")
            db.rollback()
            return {"success": False, "message": f"重命名会话失败: {str(e)}"}
    
    def get_session_info(self, user_id: str, session_id: int, db: Session = None) -> Dict[str, Any]:
        """获取会话信息"""
        if not db:
            return {"success": False, "message": "数据库连接失败"}
        
        try:
            session = db.query(Session).filter(
                Session.id == session_id,
                Session.user_id == int(user_id)
            ).first()
            
            if not session:
                return {"success": False, "message": "会话不存在或无权限"}
            
            return {
                "success": True,
                "session": session.to_dict()
            }
        except Exception as e:
            logger.error(f"获取会话信息失败: {e}")
            return {"success": False, "message": f"获取会话信息失败: {str(e)}"}
    
    def generate_session_title(self, user_message: str) -> str:
        """使用大模型生成简短的会话标题"""
        try:
            logger.info(f"开始生成会话标题，用户消息: {user_message[:50]}...")
            
            # 创建专门用于生成标题的模型实例
            llm = ChatOpenAI(
                model=settings.deepseek_model,
                temperature=0.3,  # 较低的温度以获得更稳定的结果
                max_tokens=20,    # 限制标题长度
                request_timeout=10,  # 较短的超时时间
                openai_api_key=settings.deepseek_api_key,
                openai_api_base=settings.deepseek_base_url
            )
            
            # 构建生成标题的提示词
            title_prompt = f"""请根据用户的问题生成一个简短的会话标题，要求：
1. 标题长度不超过10个字
2. 能够概括用户问题的核心内容
3. 使用简洁明了的中文
4. 不要包含标点符号
5. 直接输出标题，不要其他内容

用户问题：{user_message}"""
            
            # 调用模型生成标题
            messages = [HumanMessage(content=title_prompt)]
            response = llm.invoke(messages)
            title = response.content.strip()
            
            # 清理标题，移除可能的标点符号和多余空格
            title = title.replace('"', '').replace('"', '').replace('：', '')
            title = title.replace('？', '').replace('?', '').replace('!', '')
            title = ' '.join(title.split())  # 移除多余空格
            
            # 限制标题长度
            if len(title) > 10:
                title = title[:10]
            
            # 如果标题为空或过短，使用默认标题
            if not title or len(title) < 2:
                title = "新对话"
            
            logger.info(f"生成的会话标题: {title}")
            return title
            
        except Exception as e:
            logger.error(f"生成会话标题失败: {e}，使用默认标题")
            return "新对话"
 
chat_manager = ChatManager()